home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / isres.zip / ISRES.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-19  |  6KB  |  201 lines

  1.  
  2. {$IFDEF Windows}                                                      {!!.20}
  3.   !! ERROR: This unit is not compatible with Windows applications !!  {!!.20}
  4. {$ENDIF}                                                              {!!.20}
  5.  
  6. {$IFDEF Dpmi}                                                         {!!.20}
  7.   !! This unit cannot be used in protected mode !!                    {!!.20}
  8. {$ENDIF}                                                              {!!.20}
  9.  
  10. {$S-,R-,V-,I-,B-,F-}
  11.  
  12. {*********************************************************}
  13. {*                    ISRES.PAS 1.00                     *}
  14. {*        Copyright (c) TurboPower Software 1990.        *}
  15. {*                  All rights reserved.                 *}
  16. {*********************************************************}
  17.  
  18. unit IsRes;
  19.   {-Routines that allow a program to determine if another copy of itself is
  20.     already resident in memory}
  21.  
  22. interface
  23.  
  24. type
  25.   ProgramName = string[8];
  26.  
  27. procedure Install(Name : ProgramName; UserHook : Pointer);
  28.   {-Install this program}
  29.  
  30. procedure Uninstall;
  31.   {-Uninstall this program}
  32.  
  33. function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
  34.   {-Returns True if Name is loaded}
  35.  
  36. procedure Init16;
  37.   {-Install interrupt handler. Called automatically when program begins}
  38.  
  39. procedure Restore16;
  40.   {-Restore INT $16 vector. Called automatically when program ends}
  41.  
  42.   {==========================================================================}
  43.  
  44. implementation
  45.  
  46. type
  47.   IfcPtr = ^IfcRecord;
  48.   IfcRecord =               {*** do not change!! ***}
  49.     record
  50.       NamePtr : ^String;
  51.       Version : Word;
  52.       UserPtr : Pointer;
  53.       PrevIfc : IfcPtr;
  54.       NextIfc : IfcPtr;
  55.       PrgName : ProgramName;
  56.     end;
  57. const
  58.   IfcSignature1   = $0F0F0;    {*** do not change!! ***}
  59.   IfcSignature2   = $0E0E0;    {*** do not change!! ***}
  60. var
  61.   SaveExitProc    : Pointer;
  62.   ThisIfcPtr      : IfcPtr;
  63.   IfcInstalledPtr : ^Boolean;
  64.  
  65.   {$L ISRES.OBJ}
  66.  
  67.   procedure Init16; external;
  68.   procedure Restore16; external;
  69.   procedure ThisIfc; external;
  70.  
  71.   function GetLastModulePtr : IfcPtr;
  72.     {-Return a pointer to the last module loaded before us}
  73.   var
  74.     FoundIfc : Boolean;
  75.     P : IfcPtr;
  76.     IACAptr : Pointer absolute $40:$F0;
  77.     SaveIACA : Pointer;
  78.   begin
  79.     {assume failure}
  80.     P := nil;
  81.     SaveIACA := IACAptr;
  82.     IACAptr := nil;
  83.  
  84.     inline(
  85.       $B8/>IfcSignature1/    {mov ax,>IfcSignature1  ;standard interface function code}
  86.       $31/$FF/               {xor di,di              ;es:di = nil}
  87.       $8E/$C7/               {mov es,di}
  88.       $CD/$16/               {int $16                ;call INT 16}
  89.       $F7/$D0/               {not ax                 ;flip bits}
  90.       $3D/>IfcSignature1/    {cmp ax,>IfcSignature1  ;AX = IfcSignature1 only if INT 16 flipped bits}
  91.       $75/$1E/               {jne Done               ;Ifc handler not found?}
  92.       $8C/$C0/               {mov ax,es              ;use second method if es:di = nil}
  93.       $09/$F8/               {or ax,di}
  94.       $74/$08/               {jz NotFound}
  95.       $89/$7E/<P/            {mov [bp+<P],di         ;offset of list pointer in P}
  96.       $8C/$46/<P+2/          {mov [bp+<P+2],es       ;segment of list pointer in P}
  97.       $EB/$0C/               {jmp short Found}
  98.                              {NotFound:              ;try second method - SuperKey can defeat the first}
  99.       $B8/>IfcSignature2/    {mov ax,>IfcSignature2  ;secondary function code}
  100.       $CD/$16/               {int $16                ;call INT 16}
  101.       $F7/$D0/               {not ax                 ;AX = not AX}
  102.       $3D/>IfcSignature2/    {cmp ax,>IfcSignature2  ;AX = IfcSignature2?}
  103.       $75/$04/               {jne Done               ;Ifc handler not found?}
  104.                              {Found:}
  105.       $C6/$46/<FoundIfc/$01);{mov [bp+<FoundIfc],1   ;set Found flag}
  106.                              {Done:}
  107.  
  108.       if not FoundIfc then
  109.         GetLastModulePtr := nil
  110.       else if P <> nil then
  111.         GetLastModulePtr := P
  112.       else
  113.         GetLastModulePtr := IACAptr;
  114.  
  115.       {restore intra-applications comm. area}
  116.       IACAptr := SaveIACA;
  117.   end;
  118.  
  119.   procedure Install(Name : ProgramName; UserHook : Pointer);
  120.     {-Install this program}
  121.   var
  122.     P : IfcPtr;
  123.   begin
  124.     if (Name <> '') and not IfcInstalledPtr^ then
  125.       with ThisIfcPtr^ do begin
  126.         {see if anyone else is home}
  127.         P := GetLastModulePtr;
  128.         if P <> nil then begin
  129.           P^.NextIfc := ThisIfcPtr;
  130.           PrevIfc := P;
  131.         end
  132.         else
  133.           PrevIfc := nil;
  134.  
  135.         {initialize the other fields in the record}
  136.         PrgName := Name;
  137.         NextIfc := nil;
  138.         UserPtr := UserHook;
  139.  
  140.         IfcInstalledPtr^ := True;
  141.       end;
  142.   end;
  143.  
  144.   procedure Uninstall;
  145.     {-Uninstall this program}
  146.   begin
  147.     if IfcInstalledPtr^ then
  148.       with ThisIfcPtr^ do begin
  149.         {fix the linked list of modules}
  150.         if PrevIfc <> nil then
  151.           PrevIfc^.NextIfc := NextIfc;
  152.         if NextIfc <> nil then
  153.           NextIfc^.PrevIfc := PrevIfc;
  154.         IfcInstalledPtr^ := False;
  155.       end;
  156.   end;
  157.  
  158.   function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
  159.     {-Returns True if Name is loaded}
  160.   var
  161.     P : IfcPtr;
  162.   begin
  163.     {search backward through the list}
  164.     P := GetLastModulePtr;
  165.     while (P <> nil) do begin
  166.       if P^.NamePtr^ = Name then begin
  167.         UserHook := P^.UserPtr;
  168.         IsLoaded := True;
  169.         Exit;
  170.       end;
  171.       P := P^.PrevIfc;
  172.     end;
  173.  
  174.     {search failed}
  175.     IsLoaded := False;
  176.   end;
  177.  
  178.   {$F+}
  179.   procedure OurExitProc;
  180.     {-Error/exit handler}
  181.   begin
  182.     {restore previous exit handler}
  183.     ExitProc := SaveExitProc;
  184.  
  185.     {remove the program from the list}
  186.     Uninstall;
  187.  
  188.     {restore INT $16}
  189.     Restore16;
  190.   end;
  191.   {$F-}
  192.  
  193. begin
  194.   {take over INT $16 and initialize pointers}
  195.   Init16;
  196.  
  197.   {set up exit handler}
  198.   SaveExitProc := ExitProc;
  199.   ExitProc := @OurExitProc;
  200. end.
  201.